﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Microsoft.ResourceManagement.ObjectModel.ResourceTypes
{
    public class RmGroup : RmResource
    {
        public RmGroup()
            : base()
        {
        }

        protected const String ResourceType = @"Group";

        RmList<RmReference> explicitMember;
        RmList<RmReference> computedMember;

        protected override void EnsureAllAttributesExist()
        {
            base.EnsureAllAttributesExist();
            base.EnsureAttributeExists(AttributeNames.AccountName);
            base.EnsureAttributeExists(AttributeNames.ComputedMember);
            base.EnsureAttributeExists(AttributeNames.DisplayedOwner);
            base.EnsureAttributeExists(AttributeNames.Domain);
            base.EnsureAttributeExists(AttributeNames.DomainConfiguration);
            base.EnsureAttributeExists(AttributeNames.Email);
            base.EnsureAttributeExists(AttributeNames.ExplicitMember);
            base.EnsureAttributeExists(AttributeNames.Filter);
            base.EnsureAttributeExists(AttributeNames.MailNickname);
            base.EnsureAttributeExists(AttributeNames.MembershipAddWorkflow);
            base.EnsureAttributeExists(AttributeNames.MembershipLocked);
            base.EnsureAttributeExists(AttributeNames.MemberToAdd);
            base.EnsureAttributeExists(AttributeNames.MemberToRemove);
            base.EnsureAttributeExists(AttributeNames.ObjectSID);
            base.EnsureAttributeExists(AttributeNames.Owner);
            base.EnsureAttributeExists(AttributeNames.Scope);
            base.EnsureAttributeExists(AttributeNames.Type);
        }

        public override string GetResourceType()
        {
            return RmGroup.ResourceType;
        }

        #region promoted properties

        public RmReference Owner
        {
            get
            {
                return GetReference(AttributeNames.Owner);
            }
            set
            {
                base[AttributeNames.Owner].Value = value;
            }
        }

        public RmReference DisplayedOwner
        {
            get
            {
                return GetReference(AttributeNames.DisplayedOwner);
            }
            set
            {
                base[AttributeNames.DisplayedOwner].Value = value;
            }
        }

        public IList<RmReference> ComputedMember
        {
            get
            {
                if (this.computedMember == null)
                {
                    lock (base.Attributes)
                    {
                        this.computedMember = GetMultiValuedReference(AttributeNames.ComputedMember);
                        return this.computedMember;
                    }
                }
                else
                {
                    return this.computedMember;
                }
            }
        }

        public IList<RmReference> ExplicitMember
        {
            get
            {
                if (this.explicitMember == null)
                {
                    this.explicitMember = GetMultiValuedReference(AttributeNames.ExplicitMember);
                    return this.explicitMember;
                }
                else
                {
                    return this.explicitMember;
                }
            }
        }

        public String Domain
        {
            get
            {
                return GetString(AttributeNames.Domain);
            }
            set
            {
                base[AttributeNames.Domain].Value = value;
            }
        }

        public String Email
        {
            get
            {
                return GetString(AttributeNames.Email);
            }
            set
            {
                base[AttributeNames.Email].Value = value;
            }
        }

        public String MailNickname
        {
            get
            {
                return GetString(AttributeNames.MailNickname);
            }
            set
            {
                base[AttributeNames.MailNickname].Value = value;
            }
        }

        public bool MembershipLocked
        {
            get
            {
                return GetBoolean(AttributeNames.MembershipLocked);
            }
            set
            {
                base[AttributeNames.MembershipLocked].Value = value;
            }
        }

        public RmGroupScope Scope
        {
            get
            {
                Object o = null;
                RmAttributeValue rma = null;
                base.TryGetValue(AttributeNames.Scope, out rma);
                if (rma != null)
                    o = rma.Value;
                if (o == null)
                {
                    return RmGroupScope.Domain;
                }
                else
                {
                    return (RmGroupScope)o;
                }
            }
            set
            {
                base[AttributeNames.Scope].Value = value;
            }
        }

        public RmGroupType Type
        {
            get
            {
                Object o = null;
                RmAttributeValue rma = null;
                base.TryGetValue(AttributeNames.Type, out rma);
                if (rma != null)
                    o = rma.Value;
                if (o == null)
                {
                    return RmGroupType.Distribution;
                }
                else
                {
                    return (RmGroupType)o;
                }
            }
            set
            {
                base[AttributeNames.Type].Value = value;
            }
        }

        #endregion

        public sealed new class AttributeNames
        {
            public static RmAttributeName AccountName = new RmAttributeName(@"AccountName");
            public static RmAttributeName ComputedMember = new RmAttributeName(@"ComputedMember");
            public static RmAttributeName DisplayedOwner = new RmAttributeName(@"DisplayedOwner");
            public static RmAttributeName Domain = new RmAttributeName(@"Domain");
            public static RmAttributeName DomainConfiguration = new RmAttributeName(@"DomainConfiguration");
            public static RmAttributeName Email = new RmAttributeName(@"Email");
            public static RmAttributeName ExplicitMember = new RmAttributeName(@"ExplicitMember");
            public static RmAttributeName Filter = new RmAttributeName(@"Filter");
            public static RmAttributeName MailNickname = new RmAttributeName(@"MailNickname");
            public static RmAttributeName MemberToAdd = new RmAttributeName(@"MemberToAdd");
            public static RmAttributeName MemberToRemove = new RmAttributeName(@"MemberToRemove");
            public static RmAttributeName MembershipAddWorkflow = new RmAttributeName(@"MembershipAddWorkflow");
            public static RmAttributeName MembershipLocked = new RmAttributeName(@"MembershipLocked");
            public static RmAttributeName ObjectSID = new RmAttributeName(@"ObjectSID");
            public static RmAttributeName Owner = new RmAttributeName(@"Owner");
            public static RmAttributeName Scope = new RmAttributeName(@"Scope");
            public static RmAttributeName Type = new RmAttributeName(@"Type");
        }
    }

    public enum RmGroupScope
    {
        Global,
        Universal,
        Domain
    }

    public enum RmGroupType
    {
        Distribution = 1,
        SecurityGroup = 2,
    }
}
